package com.leenmvc.core.utils;

import java.io.*;
import java.lang.reflect.Array;
import java.util.*;

public class BeanUtils {

    /**
     * 深度克隆对象
     *
     * @param source
     * @param <T>
     * @return
     */
    public static <T> T deepClone(T source) {
        ByteArrayOutputStream bo = new ByteArrayOutputStream();
        try {
            ObjectOutputStream oo = new ObjectOutputStream(bo);
            oo.writeObject(source);
            ByteArrayInputStream bi = new ByteArrayInputStream(bo.toByteArray());
            ObjectInputStream oi = new ObjectInputStream(bi);
            return (T) oi.readObject();
        } catch (IOException e) {
            e.printStackTrace();
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 深度克隆列表
     *
     * @param source
     * @param <T>
     * @return
     */
    public static <T> List<T> deepClone(List<T> source) {
        List<T> result = new ArrayList<>();
        for(T t: source) {
            result.add(deepClone(t));
        }
        return result;
    }

    /**
     * 深度克隆Set
     *
     * @param source
     * @param <T>
     * @return
     */
    public static <T> Set<T> deepClone(Set<T> source) {
        Set<T> result = new HashSet<>();
        for(T t: source) {
            result.add(deepClone(t));
        }
        return result;
    }

    /**
     * 深度克隆Array
     *
     * @param source
     * @param <T>
     * @return
     */
    public static <T> T[] deepClone(T[] source) {
        T[] result = (T[])Array.newInstance(source[0].getClass(), source.length);
        for(int t = 0; t < source.length; t++) {
            result[t] = deepClone(source[t]);
        }
        return result;
    }

    /**
     * 深度克隆hashmap
     *
     * @param source
     * @param <K>
     * @param <V>
     * @return
     */
    public static <K,V> Map<K, V> deepClone(Map<K,V> source) {
        Map<K, V> result = new HashMap<>();
        for(K k: source.keySet()) {
            result.put(deepClone(k), deepClone(source.get(k)));
        }
        return result;
    }
 }
